package com.feng.data
{
	import com.feng.FengData;
	import com.feng.debug.logger;
	import com.feng.utils.PlayerUtils;

	import flash.utils.Dictionary;

	/**
	 * 当前状态的数据
	 * @author 风之守望者
	 * 2013-3-27
	 */
	public class StateData
	{
		/** 当前状态 */
		public var state:Array;

		/** 实际状态 */
		public var realState:Array = null;

		private var _livingPlayers:Array;

		private var _enemyList:Array;

		/** 回合数 */
		public var turnIndex:int = 0;

		/** 玩家总攻击次数 */
		public var totalAttackNum:int;

		/** 出现最高攻击者次数 */
		public var hasMaxAttackNum:int;

		/** 攻击最高攻击者次数 */
		public var attackMaxAttackNum:int;

		/** 出现最高速度者次数 */
		public var hasMaxSpeedNum:int;

		/** 攻击最高速度次数 */
		public var attackMaxSpeedNum:int;

		public var myId:int;

		/** 本轮的攻击顺序 */
		public var attackOrder:Array;

		/** 已经攻击了的玩家列表 */
		public var attackedList:Array = [];

		/** 是否为速度最快的第一次赠送攻击 */
		public var freeAttack:Boolean = false;

		/** 剩余攻击玩家 */
		public var surplusAttackOrder:Array;

		/** 当前攻击者的速度 */
		public var currentAttackerSpeed:int;

		/** 当前攻速的下死亡的玩家 */
		public var currentSpeedDiePlayers:Array = [];

		/** 当前攻速下的攻击记录 */
		public var currentSpeedAttackRecord:Array = [];

		/** 获得击杀升级的玩家 */
		public var killUpgradePlayers:Array = [];

		/** 攻击记录 */
		public var attackRecord:Array = [];

		private var _attackSortList:Array;

		private var _defenseSortList:Array;

		private var _speedSortList:Array;

		private var _hpSortList:Array;

		public function StateData()
		{

		}

		/**
		 * 更新数据
		 * @param state
		 * @param myId
		 */
		public function updateData(state:Array, myId:int):void
		{
			this.state = state;
			this.myId = myId;

			_enemyList = null;
			_livingPlayers = null;
			_attackSortList = null;
			_defenseSortList = null;
			_speedSortList = null;
			_hpSortList = null;
		}

		/** 按血量降序排列 */
		public function get hpSortList():Array
		{
			if (_hpSortList)
				return _hpSortList;
			_hpSortList.sort(function(x:*, y:*):Number
			{
				return y.hp - x.hp;
			});
			return _hpSortList;
		}

		/** 按攻速降序排列 */
		public function get speedSortList():Array
		{
			if (_speedSortList)
				return _speedSortList;
			_speedSortList = livingPlayers.concat();
			_speedSortList.sort(function(x:*, y:*):Number
			{
				return y.spd - x.spd;
			});
			return _speedSortList;
		}

		/** 按防御降序排列 */
		public function get defenseSortList():Array
		{
			if (_defenseSortList)
				return _defenseSortList;
			_defenseSortList = livingPlayers.concat();
			_defenseSortList.sort(function(x:*, y:*):Number
			{
				return y.def - x.def;
			});
			return _defenseSortList;
		}

		/** 按攻击降序排列 */
		public function get attackSortList():Array
		{
			if (_attackSortList)
				return _attackSortList;
			_attackSortList = livingPlayers.concat();
			_attackSortList.sort(function(x:*, y:*):Number
			{
				return y.atk - x.atk;
			});
			return _attackSortList;
		}

		/** 存活玩家列表 */
		public function get livingPlayers():Array
		{
			if (_livingPlayers)
				return _livingPlayers;
			_livingPlayers = [];

			for (var i:int = 0; i < state.length; i++)
			{
				if (state[i].hp == 0)
					continue;
				_livingPlayers.push(state[i]);
			}

			return _livingPlayers;
		}

		public function get enemyList():Array
		{
			if (_enemyList)
				return _enemyList;
			_enemyList = [];
			for (var i:int = 0; i < livingPlayers.length; i++)
			{
				if (livingPlayers[i].id != myId)
					_enemyList.push(livingPlayers[i]);
			}
			return _enemyList;
		}

		public function get me():Object
		{
			return state[myId];
		}

		/** 找出与我同时出手的玩家 */
		public function getSameSpeed():Array
		{
			var me:* = attackOrder.filter(function(x:*, index:int, arr:Array):Boolean
			{
				return (x.id == myId);
			})[0];

			var playerList:Array = attackOrder.filter(function(x:*, index:int, arr:Array):Boolean
			{
				return (x.spd == me.spd && x.id != me.id);
			}, me);
			var playerIdList:Array = [];
			while (playerList.length > 0)
			{
				playerIdList.push(playerList.pop().id);
			}

			return playerIdList;
		}

		/** 获取玩家可攻击次数 */
		public function getAttackNum(playerId:int):int
		{
			var attackNum:int = surplusAttackOrder.filter(function(x:*, index:int, arr:Array):Boolean
			{
				return x.id == playerId;
			}, playerId).length;
			return attackNum;
		}

		public function onBattleStart(myId:int):void
		{
			turnIndex = 0;
			realState = null;
			attackedList = [];
			attackMaxAttackNum = 0;
			attackMaxSpeedNum = 0;
			attackOrder = null;
			_attackSortList = null;
			currentAttackerSpeed = 0;
			currentSpeedAttackRecord = [];
			currentSpeedDiePlayers = [];
			_defenseSortList = null;
			_enemyList = null;
			hasMaxAttackNum = 0;
			hasMaxSpeedNum = 0;
			_hpSortList = null;
			killUpgradePlayers = [];
			attackRecord = [];
			_livingPlayers = null;
			this.myId = myId;
			_speedSortList = null;
			state = null;
			surplusAttackOrder = null;
			totalAttackNum = 0;

		}

		public function onTurn(state:Array, myId:int):void
		{
			if (realState == null)
				realState = state.concat();

			//校验 state
			if (FengData.isDebug && realState)
			{
				for (var i:int = 0; i < state.length; i++)
				{
					for (var key:String in state[i])
					{
						if (realState[i][key] != state[i][key])
						{
							logger("【本地state数据错误】");
							logger([realState, state]);
							i = state.length;
							break;
						}
					}
				}
			}
			realState = state.concat();

			updateData(state, myId);

			realState = state.concat();
			turnIndex++;
		}

		public function onAttack(state:Array, myId:int):void
		{
			updateData(state, myId);
		}

		public function onUpgrade(state:Array, myId:int, isKillUpgrade:Boolean):void
		{
			updateData(state, myId);
		}

		public function onAnyoneAttack(state:Array, myId:int, attackerId:int, targetId:int):void
		{
			var damage:int = PlayerUtils.attackDamage(realState[attackerId], realState[targetId]);

			realState[targetId].hp = realState[targetId].hp - damage;

			if (state[targetId].hp > 0 && realState[targetId].hp <= 0)
			{
				realState[targetId].hp = 0;
				currentSpeedDiePlayers.push(targetId);
				logger(targetId + "号被击杀！");
			}

			attackRecord.push({turnIndex: turnIndex, attackerId: attackerId, targetId: targetId});

			if (currentSpeedAttackRecord[targetId] == null)
				currentSpeedAttackRecord[targetId] = [];
			currentSpeedAttackRecord[targetId].push(attackerId);

			killUpgradePlayers = [];
			for (var i:int = 0; i < currentSpeedDiePlayers.length; i++)
			{
				var dieId:int = currentSpeedDiePlayers[i];
				for (var j:int = 0; j < currentSpeedAttackRecord[dieId].length; j++)
				{
					var killer:int = currentSpeedAttackRecord[dieId][j];
					if (killUpgradePlayers.indexOf(killer) == -1)
					{
						killUpgradePlayers.push(killer);
					}
				}
			}

		}

		public function onAnyoneUpgrade(state:Array, myId:int, upgraderId:int, upgradeType:int):void
		{
			if (realState == null)
				return;
			realState[upgraderId] = PlayerUtils.upgrade(realState[upgraderId], upgradeType);

			var index:int = killUpgradePlayers.indexOf(upgraderId);
			if (currentSpeedDiePlayers.length > 0 && index != -1)
			{
				realState[upgraderId].hp += 50;
				killUpgradePlayers.splice(index, 1);
			}
		}

		/** 判断是否能够拿到人头 */
		public function isCanKillSteal(playerId:int):Boolean
		{
			for each (var target:Object in state)
			{
				if (target.id != playerId && target.hp <= PlayerUtils.attackDamage(state[playerId], target))
				{
					return true;
				}
			}
			return false;
		}

		/** 上次我攻击玩到现在该玩家被攻击次数 */
		public function preTurnAttackedNum(playerId:int):int
		{
			var attackedNum:int = 0;
			for (var i:int = attackRecord.length - 1; i >= 0; i--)
			{
				if (attackRecord[i].turnIndex < turnIndex - 1)
					break;
				if (attackRecord[i].turnIndex == turnIndex - 1 && attackRecord[i].attackerId == me.id)
					break;
				if (attackRecord[i].attackerId != me.id && attackRecord[i].targetId == playerId)
					attackedNum++;
			}
			return attackedNum;
		}

		/** 获取上一回合被攻击最多的列表 */
		public function perTurnAttackedSort():Array
		{
			var attackerDic:Dictionary = new Dictionary();
			var attackedSort:Array = [];
			for (var i:int = attackRecord.length - 1; i >= 0; i--)
			{
				if (attackRecord[i].turnIndex < turnIndex - 1)
					break;
				if (attackRecord[i].turnIndex == turnIndex - 1 && attackRecord[i].attackerId == me.id)
					break;
				if (attackRecord[i].attackerId != me.id)
				{
					if (attackerDic[attackRecord[i].targetId] == null)
					{
						attackerDic[attackRecord[i].targetId] = [];
						attackedSort.push({targetId: attackRecord[i].targetId, attackerIdList: attackerDic[attackRecord[i].targetId]});
					}
					attackerDic[attackRecord[i].targetId].push(attackRecord[i].attackerId);
				}
			}
			attackedSort.sort(function(x:*, y:*):Number
			{
				if (y.attackerIdList.length != x.attackerIdList.length)
					return y.attackerIdList.length - x.attackerIdList.length;
				return state[y.targetId].hp - state[x.targetId].hp;
			});
			return attackedSort;
		}

		/** 获取一个最容易丢人头的玩家 */
		public function getMaxLostheadPlayers():Array
		{
			var maxAttacker:Object = attackSortList[0];
			//能够承受该攻击的次数
			var attackNumArr:Array = [];
			for (var i:int = 0; i < livingPlayers.length; i++)
			{
				var attackNum:Number = livingPlayers[i].hp / PlayerUtils.attackDamage(attackNumArr, livingPlayers[i]);
				attackNumArr.push({id: livingPlayers[i].id, attackNum: attackNum});
			}
			attackNumArr.sort(function(x:*, y:*):Number
			{
				return x.attackNum - y.attackNum;
			});
			return attackNumArr;
		}

		/** 获取最能抢人头的玩家 */
		public function getMaxKillStealPlayers(targetId:int):Array
		{
			var target:Object = state[targetId];
			//需要攻击次数
			var attackNumArr:Array = [];
			for (var i:int = 0; i < livingPlayers.length; i++)
			{
				if (targetId != livingPlayers[i].id)
				{
					var damage:int = PlayerUtils.attackDamage(livingPlayers[i], target);
					if (livingPlayers[i].spd == speedSortList[0].spd)
						damage = damage * 2;
					var attackNum:Number = target.hp / damage;
					attackNumArr.push({id: livingPlayers[i].id, attackNum: attackNum});
				}
			}
			attackNumArr.sort(function(x:*, y:*):Number
			{
				return x.attackNum - y.attackNum;
			});
			return attackNumArr;
		}
	}
}
